home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / isc-src / util / path.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-29  |  8.2 KB  |  391 lines

  1. static char  rcsid[] = "@(#) $Header: path.c,v 1.3 91/07/16 17:36:35 deyke Exp $";
  2.  
  3. #define _HPUX_SOURCE
  4.  
  5. #include <ctype.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <time.h>
  10.  
  11. #ifdef __STDC__
  12. #define __ARGS(x)       x
  13. #else
  14. #define __ARGS(x)       ()
  15. #endif
  16.  
  17. #define NULLCHAR        ((char *) 0)
  18.  
  19. #define ALEN            6       /* Number of chars in callsign field */
  20. #define AXALEN          7       /* Total AX.25 address length, including SSID */
  21. #define SSID            0x1e    /* Sub station ID */
  22.  
  23. #define AXROUTESIZE     499
  24.  
  25. struct iface {
  26.   struct iface *next;
  27.   char *name;
  28.   int cnt;
  29. };
  30.  
  31. struct axroute_tab {
  32.   char call[AXALEN];
  33.   struct axroute_tab *digi;
  34.   struct iface *ifp;
  35.   long time;
  36.   struct axroute_tab *next;
  37. };
  38.  
  39. struct axroute_saverecord_1 {
  40.   char call[AXALEN];
  41.   char digi[AXALEN];
  42.   long time;
  43. /*char ifname[]; */
  44. };
  45.  
  46. static char axroutefile[] = "/tcp/axroute_data";
  47. static struct axroute_tab *axroute_tab[AXROUTESIZE];
  48. static struct iface *Ifaces;
  49.  
  50. static void swap4 __ARGS((char *p));
  51. static int axroute_hash __ARGS((char *call));
  52. static struct axroute_tab *axroute_tabptr __ARGS((char *call, int create));
  53. static struct iface *ifaceptr __ARGS((char *name));
  54. static void axroute_loadfile __ARGS((void));
  55. static void doroutelistentry __ARGS((struct axroute_tab *rp));
  56. static int doroutelist __ARGS((int argc, char *argv []));
  57. static int doroutestat __ARGS((void));
  58. static void hash_performance __ARGS((void));
  59.  
  60. /*---------------------------------------------------------------------------*/
  61.  
  62. #ifdef __TURBOC__       /* PC specific functions */
  63.  
  64. static void swap4(p)
  65. char  *p;
  66. {
  67.   char  t;
  68.  
  69.   t = p[0];
  70.   p[0] = p[3];
  71.   p[3] = t;
  72.  
  73.   t = p[1];
  74.   p[1] = p[2];
  75.   p[2] = t;
  76. }
  77.  
  78. #endif
  79.  
  80. /*---------------------------------------------------------------------------*/
  81.  
  82. /* Convert encoded AX.25 address to printable string */
  83. char *
  84. pax25(e,addr)
  85. char *e;
  86. char *addr;
  87. {
  88.     register int i;
  89.     char c;
  90.     char *cp;
  91.  
  92.     cp = e;
  93.     for(i=ALEN;i != 0;i--){
  94.         c = (*addr++ >> 1) & 0x7f;
  95.         if(c != ' ')
  96.             *cp++ = c;
  97.     }
  98.     if ((*addr & SSID) != 0)
  99.         sprintf(cp,"-%d",(*addr >> 1) & 0xf);   /* ssid */
  100.     else
  101.         *cp = '\0';
  102.     return e;
  103. }
  104.  
  105. /*---------------------------------------------------------------------------*/
  106.  
  107. /*
  108.  * setcall - convert callsign plus substation ID of the form
  109.  * "KA9Q-0" to AX.25 (shifted) address format
  110.  *   Address extension bit is left clear
  111.  *   Return -1 on error, 0 if OK
  112.  */
  113. int
  114. setcall(out,call)
  115. char *out;
  116. char *call;
  117. {
  118.     int csize;
  119.     unsigned ssid;
  120.     register int i;
  121.     register char *dp;
  122.     char c;
  123.  
  124.     if(out == NULLCHAR || call == NULLCHAR || *call == '\0'){
  125.         return -1;
  126.     }
  127.     /* Find dash, if any, separating callsign from ssid
  128.      * Then compute length of callsign field and make sure
  129.      * it isn't excessive
  130.      */
  131.     dp = strchr(call,'-');
  132.     if(dp == NULLCHAR)
  133.         csize = strlen(call);
  134.     else
  135.         csize = dp - call;
  136.     if(csize > ALEN)
  137.         return -1;
  138.     /* Now find and convert ssid, if any */
  139.     if(dp != NULLCHAR){
  140.         dp++;   /* skip dash */
  141.         ssid = atoi(dp);
  142.         if(ssid > 15)
  143.             return -1;
  144.     } else
  145.         ssid = 0;
  146.     /* Copy upper-case callsign, left shifted one bit */
  147.     for(i=0;i<csize;i++){
  148.         c = *call++;
  149.         if(islower(c))
  150.             c = toupper(c);
  151.         *out++ = c << 1;
  152.     }
  153.     /* Pad with shifted spaces if necessary */
  154.     for(;i<ALEN;i++)
  155.         *out++ = ' ' << 1;
  156.  
  157.     /* Insert substation ID field and set reserved bits */
  158.     *out = 0x60 | (ssid << 1);
  159.     return 0;
  160. }
  161.  
  162. /*---------------------------------------------------------------------------*/
  163.  
  164. int
  165. addreq(a,b)
  166. register char *a,*b;
  167. {
  168.     if (*a++ != *b++) return 0;
  169.     if (*a++ != *b++) return 0;
  170.     if (*a++ != *b++) return 0;
  171.     if (*a++ != *b++) return 0;
  172.     if (*a++ != *b++) return 0;
  173.     if (*a++ != *b++) return 0;
  174.     return (*a & SSID) == (*b & SSID);
  175. }
  176.  
  177. /*---------------------------------------------------------------------------*/
  178.  
  179. void
  180. addrcp(to,from)
  181. register char *to,*from;
  182. {
  183.     *to++ = *from++;
  184.     *to++ = *from++;
  185.     *to++ = *from++;
  186.     *to++ = *from++;
  187.     *to++ = *from++;
  188.     *to++ = *from++;
  189.     *to = (*from & SSID) | 0x60;
  190. }
  191.  
  192. /*---------------------------------------------------------------------------*/
  193.  
  194. static int  axroute_hash(call)
  195. char  *call;
  196. {
  197.   long  hashval;
  198.  
  199.   hashval  = ((*call++ << 23) & 0x0f000000);
  200.   hashval |= ((*call++ << 19) & 0x00f00000);
  201.   hashval |= ((*call++ << 15) & 0x000f0000);
  202.   hashval |= ((*call++ << 11) & 0x0000f000);
  203.   hashval |= ((*call++ <<  7) & 0x00000f00);
  204.   hashval |= ((*call++ <<  3) & 0x000000f0);
  205.   hashval |= ((*call   >>  1) & 0x0000000f);
  206.   return hashval % AXROUTESIZE;
  207. }
  208.  
  209. /*---------------------------------------------------------------------------*/
  210.  
  211. static struct axroute_tab *axroute_tabptr(call, create)
  212. char  *call;
  213. int  create;
  214. {
  215.  
  216.   int  hashval;
  217.   struct axroute_tab *rp;
  218.  
  219.   hashval = axroute_hash(call);
  220.   for (rp = axroute_tab[hashval]; rp && !addreq(rp->call, call); rp = rp->next) ;
  221.   if (!rp && create) {
  222.     rp = (struct axroute_tab *) calloc(1, sizeof(struct axroute_tab ));
  223.     addrcp(rp->call, call);
  224.     rp->next = axroute_tab[hashval];
  225.     axroute_tab[hashval] = rp;
  226.   }
  227.   return rp;
  228. }
  229.  
  230. /*---------------------------------------------------------------------------*/
  231.  
  232. static struct iface *ifaceptr(name)
  233. char *name;
  234. {
  235.   struct iface *ifp;
  236.  
  237.   if (!*name) return 0;
  238.   for (ifp = Ifaces; ifp && strcmp(ifp->name, name); ifp = ifp->next) ;
  239.   if (!ifp) {
  240.     ifp = calloc(1, sizeof(*ifp));
  241.     ifp->name = strdup(name);
  242.     ifp->next = Ifaces;
  243.     Ifaces = ifp;
  244.   }
  245.   ifp->cnt++;
  246.   return ifp;
  247. }
  248.  
  249. /*---------------------------------------------------------------------------*/
  250.  
  251. static void axroute_loadfile()
  252. {
  253.  
  254.   FILE * fp;
  255.   char *cp;
  256.   char ifname[1024];
  257.   int c;
  258.   struct axroute_saverecord_1 buf;
  259.   struct axroute_tab *rp;
  260.  
  261.   if (!(fp = fopen(axroutefile, "rb"))) return;
  262.   getc(fp);
  263.   while (fread(&buf, sizeof(buf), 1, fp)) {
  264.     cp = ifname;
  265.     do {
  266.       if ((c = getc(fp)) == EOF) {
  267.     fclose(fp);
  268.     return;
  269.       }
  270.     } while (*cp++ = c);
  271.     rp = axroute_tabptr(buf.call, 1);
  272.     if (buf.digi[0]) rp->digi = axroute_tabptr(buf.digi, 1);
  273.     rp->ifp = ifaceptr(ifname);
  274.     rp->time = buf.time;
  275. #ifdef __TURBOC__
  276.     swap4((char *) & rp->time);
  277. #endif
  278.   }
  279.   fclose(fp);
  280. }
  281.  
  282. /*---------------------------------------------------------------------------*/
  283.  
  284. static void doroutelistentry(rp)
  285. struct axroute_tab *rp;
  286. {
  287.  
  288.   char *cp, buf[1024];
  289.   int i, n;
  290.   struct axroute_tab *rp_stack[20];
  291.   struct iface *ifp = 0;
  292.   struct tm *tm;
  293.  
  294.   tm = gmtime(&rp->time);
  295.   cp = pax25(buf, rp->call);
  296.   for (n = 0; rp; rp = rp->digi) {
  297.     rp_stack[++n] = rp;
  298.     ifp = rp->ifp;
  299.   }
  300.   for (i = n; i > 1; i--) {
  301.     strcat(cp, i == n ? " via " : ",");
  302.     while (*cp) cp++;
  303.     pax25(cp, rp_stack[i]->call);
  304.   }
  305.   printf("%2d-%.3s  %-9s  %s\n",
  306.      tm->tm_mday,
  307.      "JanFebMarAprMayJunJulAugSepOctNovDec" + 3 * tm->tm_mon,
  308.      ifp ? ifp->name : "???",
  309.      buf);
  310. }
  311.  
  312. /*---------------------------------------------------------------------------*/
  313.  
  314. static int  doroutelist(argc, argv)
  315. int  argc;
  316. char  *argv[];
  317. {
  318.  
  319.   char  call[AXALEN];
  320.   int  i;
  321.   struct axroute_tab *rp;
  322.  
  323.   puts("Date    Interface  Path");
  324.   if (argc < 2) {
  325.     for (i = 0; i < AXROUTESIZE; i++)
  326.       for (rp = axroute_tab[i]; rp; rp = rp->next) doroutelistentry(rp);
  327.     return 0;
  328.   }
  329.   argc--;
  330.   argv++;
  331.   for (; argc > 0; argc--, argv++)
  332.     if (setcall(call, *argv) || !(rp = axroute_tabptr(call, 0)))
  333.       printf("** Not in table ** %s\n", *argv);
  334.     else
  335.       doroutelistentry(rp);
  336.   return 0;
  337. }
  338.  
  339. /*---------------------------------------------------------------------------*/
  340.  
  341. static int doroutestat()
  342. {
  343.  
  344.   int total = 0;
  345.   struct iface *ifp;
  346.  
  347.   puts("Interface  Count");
  348.   for (ifp = Ifaces; ifp; ifp = ifp->next) {
  349.     printf("%-9s  %5d\n", ifp->name, ifp->cnt);
  350.     total += ifp->cnt;
  351.   }
  352.   puts("---------  -----");
  353.   printf("  total    %5d\n", total);
  354.   return 0;
  355. }
  356.  
  357. /*---------------------------------------------------------------------------*/
  358.  
  359. static void hash_performance()
  360. {
  361.  
  362.   int  i, len;
  363.   struct axroute_tab *rp;
  364.  
  365.   puts("Index  Length");
  366.   for (i = 0; i < AXROUTESIZE; i++) {
  367.     len = 0;
  368.     for (rp = axroute_tab[i]; rp; rp = rp->next) len++;
  369.     printf("%5d  %6d  ", i, len);
  370.     while (len--) putchar('*');
  371.     putchar('\n');
  372.   }
  373. }
  374.  
  375. /*---------------------------------------------------------------------------*/
  376.  
  377. int  main(argc, argv)
  378. int  argc;
  379. char  **argv;
  380. {
  381.   axroute_loadfile();
  382.   if (!strcmp(argv[1], "hash"))
  383.     hash_performance();
  384.   else if (!strcmp(argv[1], "stat"))
  385.     doroutestat();
  386.   else
  387.     doroutelist(argc, argv);
  388.   return 0;
  389. }
  390.  
  391.